package jee.boot.module.oauth2.config;

import jee.boot.common.properties.PermitUrlProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler;

/**
 * spring security配置,不拦截oauth要开放的资源
 */
@Configuration
@EnableConfigurationProperties(PermitUrlProperties.class)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
	@Autowired
	private UserDetailsService userDetailsService;

	@Autowired
	private PasswordEncoder passwordEncoder;

	@Autowired
	private OauthLogoutHandler oauthLogoutHandler;
	@Autowired
	private PermitUrlProperties permitUrlProperties;

	@Override
	public void configure(WebSecurity web) throws Exception {
//		web.ignoring().antMatchers("/v2/api-docs", "/configuration/ui", "/swagger-resources", "/configuration/security", "/swagger-ui.html", "/webjars/**", "/doc.html", "/login.html");
//		web.ignoring().antMatchers("/js/**");
//		web.ignoring().antMatchers("/css/**");
//		web.ignoring().antMatchers("/health");
		// 忽略登录界面
		web.ignoring().antMatchers("/login.html");
//		web.ignoring().antMatchers("/hello.html");
	}

	/**
	 * 认证管理
	 *
	 * @return 认证管理对象
	 * @throws Exception
	 *             认证异常信息
	 */
	@Override
	@Bean
	public AuthenticationManager authenticationManagerBean() throws Exception {
		return super.authenticationManagerBean();
	}

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		// @formatter:off
		http
			//禁用csrf
			.csrf().disable()
			//请求过滤
			.authorizeRequests()
				.antMatchers(permitUrlProperties.getHttpUrls()).permitAll()
				.anyRequest().authenticated()
				.and()
			//登录配置
			.formLogin()
				.loginPage("/login.html")
				.loginProcessingUrl("/user/login")
				.and()
			// 授权码模式需要session的支持，此模式可以支持所有oauth2的认证
			.sessionManagement()
				.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
				.and()
			//登出配置
			.logout()
				.logoutUrl("/user/logout")
				.clearAuthentication(true)
				.logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler())
				.addLogoutHandler(oauthLogoutHandler)
				.and()
			// 解决不允许显示在iframe的问题
			.headers()
				.frameOptions().disable()
				.cacheControl()
				.and();
		// @formatter:on
	}

	/**
	 * 全局用户信息
	 *
	 * @param auth
	 *            认证管理
	 * @throws Exception
	 *             用户认证异常信息
	 */
	@Autowired
	public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
		auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
	}

}
